﻿using System;
using System.Collections.Generic;
using System.Text;
using CSharp.Libs.WPF;
using CSharp.Libs.Net;
using CSharp.Libs.Misc;
using CSharp.Libs.Koc;
using CSharp.Libs.ExceptionHandling;
using System.Windows.Input;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Timers;



namespace KocChatWriter
{
    class MainWindowViewModel : ViewModelBase
    {
        #region declarations
        private ExceptionCollector _EC = null;
        private URLHolder _UH = null;
        private Timer _TMR = null;

        private RelayCommand _rcExecuteGetChat = null;
        private RelayCommand _rcActivateDeactivateTimer = null;

        private String _strApplicationStartupPath = "";
        private String _strServerNumber = "";
        private String _strUrlGetChat = "";
        private String _strResult = "";

        private Int32 _intNextGlobalIDX = 0;
        private Int32 _intNextAllianceIDX = 0;
        private Int32 _intNextWhisperIDX = 0;

        private const String PARAM_CUR_NEWEST_1 = "curNewest1";
        private const String PARAM_CUR_NEWEST_2 = "curNewest2";
        private const String PARAM_CUR_NEWEST_3 = "curNewest3";

        private const String KEY_DATA = "data";
        private const String KEY_REQ_MICRO_TIME = "reqmicrotime";
        private const String KEY_RES_MICRO_TIME = "resmicrotime";
        private const String KEY_NEW_CHATS = "newChats";
        private const String KEY_NEXT_NEWEST = "nextNewests";
        private const String KEY_CHAT_GLOBAL = "1";
        private const String KEY_CHAT_ALLIANCE = "2";
        private const String KEY_CHAT_WHISPER = "3";
        private const Int32 KEY_CHAT_ITEM_USER_NAME = 0;
        private const Int32 KEY_CHAT_ITEM_TIME = 1;
        private const Int32 KEY_CHAT_ITEM_AVATAR = 2;
        private const Int32 KEY_CHAT_ITEM_TEXT = 3;
        private const Int32 KEY_CHAT_ITEM_USER_ID = 4;
        private const Int32 KEY_CHAT_ITEM_UNKNOWN_1 = 5;
        private const Int32 KEY_CHAT_ITEM_UNKNOWN_2 = 6;

        private const String DATE_TIME_STAMP_MASK_LOG_ENTRY = "dd.MM.yyyy HH:mm:ss";
        #endregion



        #region constructor / terminator
        public MainWindowViewModel()
        {
            _EC = new ExceptionCollector();
            _UH = new URLHolder(_EC);
            _TMR = new Timer();
            _TMR.Interval = 5000;
            _TMR.Elapsed += new ElapsedEventHandler(_TMR_Elapsed);

            //Set default paths
            _strApplicationStartupPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        }

        ~MainWindowViewModel()
        {
            _TMR.Stop();
            _TMR.Dispose();
            _TMR = null;
            _UH = null;
            _EC.Dispose();
            _EC = null;
        }
        #endregion



        #region event handling
        void _TMR_Elapsed(object sender, ElapsedEventArgs e)
        {
            _ExecuteGetChat();
        }
        #endregion



        #region private functions
        private void _SetUrlGetChat()
        {
            try
            {
                _UH.ParseURLGetChat(_strUrlGetChat);

                _GetServerNumber();

                OnPropertyChanged("UrlGetChat");
                OnPropertyChanged("UrlGetChatValidness");
                OnPropertyChanged("New1");
                OnPropertyChanged("New2");
                OnPropertyChanged("New3");
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _RefreshURL()
        {
            try
            {
                _strUrlGetChat = _UH.URLGetChat.GetURL();
                OnPropertyChanged("UrlGetChat");
                OnPropertyChanged("UrlGetChatValidness");
                OnPropertyChanged("New1");
                OnPropertyChanged("New2");
                OnPropertyChanged("New3");
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _GetServerNumber()
        {
            try
            {
                if (_UH.URLGetChat.URLMaybeValid)
                {
                    String strIdxSeek = "//www";
                    Int32 Idx = _strUrlGetChat.IndexOf(strIdxSeek) + strIdxSeek.Length;

                    _strServerNumber = "";
                    while (Idx < _strUrlGetChat.Length)
                    {
                        if (_strUrlGetChat.Substring(Idx, 1) == ".")
                        {
                            break;
                        }
                        _strServerNumber = String.Concat(_strServerNumber, _strUrlGetChat.Substring(Idx, 1));
                        Idx++;
                    }
                }
                else
                {
                    _strServerNumber = "x";
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _ResetResult()
        {
            try
            {
                _strResult = "";
                OnPropertyChanged("Result");
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private void _ExecuteGetChat()
        {
            try
            {
                String NL = Environment.NewLine;

                _strResult = String.Concat(
                    "Global      : ", _intNextGlobalIDX.ToString(), NL,
                    "Alliance    : ", _intNextAllianceIDX.ToString(), NL,
                    "Whisper     : ", _intNextWhisperIDX.ToString(), NL,
                    "Last Trigger: ", DateTime.Now.ToString(DATE_TIME_STAMP_MASK_LOG_ENTRY));

                if (_UH.URLGetChat.URLMaybeValid)
                {
                    //Set last time saved NEXT Idx as startup Parameter
                    _UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_1] = _intNextGlobalIDX.ToString();
                    _UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_2] = _intNextAllianceIDX.ToString();
                    _UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_3] = _intNextWhisperIDX.ToString();

                    //
                    Hashtable htResult = null;
                    if (_UH.URLGetChat.GetAnswerHashtable(out htResult))
                    {
                        //Get Data Hashtable
                        Hashtable htData = htResult[KEY_DATA] as Hashtable;
                        if (htData != null)
                        {
                            //Get NewChats and NextNewest Hashtables
                            Hashtable htNewChats = htData[KEY_NEW_CHATS] as Hashtable;
                            Hashtable htNextNewest = htData[KEY_NEXT_NEWEST] as Hashtable;
                            if (htNewChats != null &&
                                htNextNewest != null)
                            {
                                //Get all Chats
                                ArrayList alGlobalChats = htNewChats[KEY_CHAT_GLOBAL] as ArrayList;
                                ArrayList alAllianceChats = htNewChats[KEY_CHAT_ALLIANCE] as ArrayList;
                                ArrayList alWhisperChats = htNewChats[KEY_CHAT_WHISPER] as ArrayList;

                                if (alGlobalChats != null &&
                                    alAllianceChats != null &&
                                    alWhisperChats != null)
                                {
                                    //Get next IDs
                                    Int32.TryParse(htNextNewest[KEY_CHAT_GLOBAL].ToString(), out _intNextGlobalIDX);
                                    Int32.TryParse(htNextNewest[KEY_CHAT_ALLIANCE].ToString(), out _intNextAllianceIDX);
                                    Int32.TryParse(htNextNewest[KEY_CHAT_WHISPER].ToString(), out _intNextWhisperIDX);

                                    //Get Global ChatItems
                                    if (alGlobalChats.Count > 0)
                                    {
                                        StreamWriter SW = _GetSwGlobalChat();

                                        foreach (ArrayList alCI in alGlobalChats)
                                        {
                                            SW.WriteLine(String.Concat(
                                                alCI[KEY_CHAT_ITEM_USER_NAME].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_USER_ID].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_TIME].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_TEXT].ToString().Replace((Char)09, ' ')));
                                        }

                                        SW.Close();
                                        SW.Dispose();
                                        SW = null;
                                    }

                                    //Get Alliance ChatItems
                                    if (alAllianceChats.Count > 0)
                                    {
                                        StreamWriter SW = _GetSwAllianceChat();

                                        foreach (ArrayList alCI in alAllianceChats)
                                        {
                                            SW.WriteLine(String.Concat(
                                                alCI[KEY_CHAT_ITEM_USER_NAME].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_USER_ID].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_TIME].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_TEXT].ToString().Replace((Char)09, ' ')));
                                        }

                                        SW.Close();
                                        SW.Dispose();
                                        SW = null;
                                    }

                                    //Get Whisper ChatItems
                                    if (alWhisperChats.Count > 0)
                                    {
                                        StreamWriter SW = _GetSwWhisperChat();

                                        foreach (ArrayList alCI in alWhisperChats)
                                        {
                                            SW.WriteLine(String.Concat(
                                                alCI[KEY_CHAT_ITEM_USER_NAME].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_USER_ID].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_TIME].ToString().Replace((Char)09, ' '), (Char)09,
                                                alCI[KEY_CHAT_ITEM_TEXT].ToString().Replace((Char)09, ' ')));
                                        }

                                        SW.Close();
                                        SW.Dispose();
                                        SW = null;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        _strResult = "";
                    }
                }

                OnPropertyChanged("Result");
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        private StreamWriter _GetSwGlobalChat()
        {
            try
            {
                String strFileName = String.Concat(_strApplicationStartupPath, "\\", "ChatLogGlobal", _strServerNumber, ".csv");
                
                StreamWriter SW = null;

                if (!File.Exists(strFileName))
                {
                    SW = File.AppendText(strFileName);
                    SW.WriteLine(String.Concat("UserName", (Char)09, "UserID", (Char)09, "Time", (Char)09, "Text"));
                    return SW;
                }
                
                SW = File.AppendText(strFileName);
                return SW;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return null;
        }

        private StreamWriter _GetSwAllianceChat()
        {
            try
            {
                String strFileName = String.Concat(_strApplicationStartupPath, "\\", "ChatLogAlliance", _strServerNumber, ".csv");

                StreamWriter SW = null;

                if (!File.Exists(strFileName))
                {
                    SW = File.AppendText(strFileName);
                    SW.WriteLine(String.Concat("UserName", (Char)09, "UserID", (Char)09, "Time", (Char)09, "Text"));
                    return SW;
                }

                SW = File.AppendText(strFileName);
                return SW;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return null;
        }

        private StreamWriter _GetSwWhisperChat()
        {
            try
            {
                String strFileName = String.Concat(_strApplicationStartupPath, "\\", "ChatLogWhisper", _strServerNumber, ".csv");

                StreamWriter SW = null;

                if (!File.Exists(strFileName))
                {
                    SW = File.AppendText(strFileName);
                    SW.WriteLine(String.Concat("UserName", (Char)09, "UserID", (Char)09, "Time", (Char)09, "Text"));
                    return SW;
                }

                SW = File.AppendText(strFileName);
                return SW;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return null;
        }

        private void _ActivateDeactivateTimer()
        {
            try
            {
                if (_TMR.Enabled)
                {
                    _TMR.Stop();
                }
                else
                {
                    _TMR.Start();
                }

                OnPropertyChanged("TimerActive");
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }
        #endregion



        #region interface
        #region properties
        public String UrlGetChat
        {
            get
            {
                return _strUrlGetChat;
            }
            set
            {
                _strUrlGetChat = value;
                _SetUrlGetChat();
            }
        }

        public String UrlGetChatValidness
        {
            get
            {
                if (_UH.URLGetChat.URLMaybeValid)
                {
                    return "OK";
                }
                else
                {
                    return "FALSE";
                }
            }
        }

        public String New1
        {
            get
            {
                if (_UH.URLGetChat.URLMaybeValid)
                {
                    return _UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_1];
                }
                else
                {
                    return "";
                }
            }
            set
            {
                //_UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_1] = value;
                _RefreshURL();
            }
        }

        public String New2
        {
            get
            {
                if (_UH.URLGetChat.URLMaybeValid)
                {
                    return _UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_2];
                }
                else
                {
                    return "";
                }
            }
            set
            {
                //_UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_2] = value;
                _RefreshURL();
            }
        }

        public String New3
        {
            get
            {
                if (_UH.URLGetChat.URLMaybeValid)
                {
                    return _UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_3];
                }
                else
                {
                    return "";
                }
            }
            set
            {
                //_UH.URLGetChat.Parameters[PARAM_CUR_NEWEST_3] = value;
                _RefreshURL();
            }
        }

        public ICommand ExecuteGetChat
        {
            get
            {
                if (_rcExecuteGetChat == null)
                {
                    _rcExecuteGetChat = new RelayCommand(
                        param => this._ExecuteGetChat(),
                        param => this.CanExecuteGetChat);
                }
                return _rcExecuteGetChat;
            }
        }
        public Boolean CanExecuteGetChat
        {
            get
            {
                return true;
            }
        }

        public String Result
        {
            get
            {
                return _strResult;
            }
        }

        public String TimerActive
        {
            get
            {
                return _TMR.Enabled.ToString();
            }
        }

        public ICommand ActivateDeactivateTimer
        {
            get
            {
                if (_rcActivateDeactivateTimer == null)
                {
                    _rcActivateDeactivateTimer = new RelayCommand(
                        param => this._ActivateDeactivateTimer(),
                        param => this.CanActivateDeactivateTimer);
                }
                return _rcActivateDeactivateTimer;
            }
        }
        public Boolean CanActivateDeactivateTimer
        {
            get
            {
                return true;
            }
        }
        #endregion

        #region methods
        #endregion
        #endregion
    }
}

/*
        #region declarations
        #endregion



        #region constructor / terminator
        #endregion



        #region private functions
        #endregion



        #region interface
        #region properties
        #endregion

        #region methods
        #endregion
        #endregion
*/